package nodes;

import java.lang.reflect.Array;
import java.util.ArrayList;

import nodes.visitor.NodeVisitor;

import func.Function;

public class FuncNode<T> implements Node<T> {

	private Function<T> func;
	private ArrayList<Node<T>> children;
	
	public FuncNode(Function<T> func, ArrayList<Node<T>> children) {
		this.func = func;
		this.children = children;
	}
	
	public String getName() {
		return func.description();
	}
	
	public ArrayList<Node<T>> getChildren() {
		return children;
	}
	
	public void setChildren(ArrayList<Node<T>> children) {
		this.children = children;
	}
	
	public void accept(NodeVisitor v) {
		v.visitFuncNode(this);
	}
	
	@SuppressWarnings("unchecked")
	public T evaluate(T[] param) {
		T[] results = (T[]) Array.newInstance(
				param.getClass().getComponentType(), children.size());
		for(int i = 0; i < children.size(); i++)
			results[i] = children.get(i).evaluate(param);
		
		return func.applyFunction(results);
	}
	
	public Node<T> copyNode() {
		ArrayList<Node<T>> copyChildren = new ArrayList<Node<T>>(3);
		for(Node<T> child : children)
			copyChildren.add(child.copyNode());
		
		return new FuncNode<T>(func, copyChildren);
	}
}
